// Copyright (c) 2025, 大连理工大学 (Dalian University of Technology)
//
// Licensed under the Mulan PSL v2.
// You can use this file according to the terms and conditions of the Mulan PSL v2.
// You may obtain a copy of the License at
//
//     http://license.coscl.org.cn/MulanPSL2
//
// THIS SOFTWARE IS PROVIDED ON AN "AS IS" BASIS, WITHOUT WARRANTIES OF ANY KIND,
// EITHER EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO NON-INFRINGEMENT,
// MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE. SEE THE MULAN PSL v2
// FOR MORE DETAILS.

#include "QUAD4IntegStressService.h"

#include <cassert>
#include <cstring>
#include <memory>

using namespace SG::DBManager;
using namespace SG::DataStructure;

// 注册服务
SERVICE_REG_IMPL1 (QUAD4IntegStressService, IQUAD4IntegStressRepository)

QUAD4IntegStressService::QUAD4IntegStressService (IQUAD4IntegStressRepository& repos) : m_repository (repos)
{}

QUAD4IntegStressService::~QUAD4IntegStressService ()
{}

bool QUAD4IntegStressService::AddBySubcaseId (SG::DataStructure::Common::Id subcaseId, std::vector<SG::Algebra::Matrixd>& data)
{
    std::size_t perMatrixRow  = 6;
    std::size_t perMatrixCol  = 4;
    std::size_t perMatrixNums = perMatrixRow * perMatrixCol;
    size_t      matrixSize    = data.size ();
    if (matrixSize == 0)
        return true;
    if (data[0].GetColSize () != perMatrixCol || data[0].GetRowSize () != perMatrixRow)
        return false;

    std::vector<SG::DataStructure::Common::Real> writeData (matrixSize * perMatrixNums);
    SG::DataStructure::Common::Real*             writeDataAddress = writeData.data ();  // 每次矩阵在writeData复制的首地址

    for (auto& curMatrix : data)
    {
        auto MatrixDataBegin = curMatrix[0];
        std::memcpy (writeDataAddress, MatrixDataBegin, perMatrixNums * sizeof (SG::DataStructure::Common::Real));
        writeDataAddress += perMatrixNums;
    }

    m_repository.Add (subcaseId, writeData);
    return true;
}

bool QUAD4IntegStressService::FindBySubcaseId (SG::DataStructure::Common::Id subcaseId, std::vector<SG::Algebra::Matrixd>& _OUT data) const
{
    std::size_t perMatrixRow  = 6;
    std::size_t perMatrixCol  = 4;
    std::size_t perMatrixNums = perMatrixRow * perMatrixCol;

    std::vector<SG::DataStructure::Common::Real> readData;
    m_repository.FindBySubcaseId (subcaseId, readData);
    auto        iterBegin  = readData.begin ();
    std::size_t matrixSize = readData.size () / perMatrixNums;

    for (size_t i = 0; i < matrixSize; i++)
    {
        data.push_back ({ perMatrixRow, perMatrixCol, std::vector<double> (iterBegin, iterBegin + perMatrixNums) });
        iterBegin += perMatrixNums;
    }

    return true;
}